package com.entity;

//自己来模拟实现一个阻塞队列
//基于数组的方式来实现，提供 2 个核心方法：
// 1. put方法 入队列
// 2.take方法 出队列
public class MyBlockingQueue {
    //假定最大是 1000 个元素，当然也可以设定成 可配置的
    private int[] items = new int[1000];
    //对首的位置
    private int head = 0;
    //对尾的位置
    private int tail = 0;
    //队列的元素个数
    volatile private int size = 0;

    //入队列
    public void put(int value) throws InterruptedException {
        synchronized (this) {
            while (size == items.length) {
                //队列已满，无法插入
                this.wait();
            }
            //队列没满，入队列
            items[tail] = value;
            tail++;
            if (tail == items.length) {
                //判断 tail 是否到达末尾
                //如果 tail 到达末尾，就需要从头开始
                tail = 0;
            }
            size++;

            //插入元素成功，说明队列不空，就要唤醒
            this.notify();
        }
    }

    //出队列
    public Integer take() throws InterruptedException { //int 不可以返回 null，Integer 可以返回 null
        int ret = 0;
        synchronized (this) {
            while (size == 0) {
                //队列为空，就等待
                this.wait();
            }
            //队列不为空，则 取出队首元素
            ret = items[head];
            head++;
            if (head == items.length) {
                head = 0;
            }
            size--;

            //当取走一个元素成功，说明队列不满，就要唤醒
            this.notify();
        }
        return ret;
    }

}
